﻿package core.ui
{
    import core.drawing.*;
    import core.enum.*;
    import core.event.*;
    import core.image.*;
    import core.ui.controls.*;
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.ui.*;

    public class Canvas extends CanvasHolder
    {
        public var history:History;
        public var document:Document;
        public var selection:Selection;
        public var zoomlevel:Number = 1;
        public var screenshot:BitmapData;
        public var clip:Rectangle;
        public var clipox:int;
        public var clipoy:int;
        public var clipsx:int;
        public var clipsy:int;
        var point:Point;
        var cm:ContextMenu;

        public function Canvas(param1:Tuyitu, param2:Document)
        {
            this.clip = new Rectangle();
            this.point = new Point();
            super(param1, param2.name);
            this.document = param2;
            this.history = new History(param1, this, 15);
            SetImageSizeInfo(this.dw, this.dh);
            holder.addChild(param2);
            this.screenshot = new BitmapData(this.dw, this.dh, true, 16777215);
            ztb.addEventListener(NumberEvent.CHANGE, this.SetZoomEvent, false, 1, true);
            grip.addEventListener(MouseEvent.MOUSE_DOWN, this.GripMouseDown, false, 0, true);
            hscroll.addEventListener(ScrollEvent.SCROLL, this.HorizontalScroll, false, 0, true);
            vscroll.addEventListener(ScrollEvent.SCROLL, this.VerticalScroll, false, 0, true);
            this.UpdateAfterEdit();
            return;
        }// end function

        public function get dw() : int
        {
            return this.document.dw;
        }// end function

        public function get dh() : int
        {
            return this.document.dh;
        }// end function

        public function get layer() : Layer
        {
            return this.document.GetLayer();
        }// end function

        public function BindTool(Document:Tool) : void
        {
            back.addEventListener(MouseEvent.MOUSE_DOWN, Document.MouseDown, false, 0, true);
            if (Document.moveevent)
            {
                back.addEventListener(MouseEvent.MOUSE_MOVE, Document.MouseMove, false, 0, true);
            }
            Document.Reset();
            this.SetContextMenu(Document.type);
            return;
        }// end function

        public function UnbindTool(Document:Tool) : void
        {
            back.removeEventListener(MouseEvent.MOUSE_DOWN, Document.MouseDown, false);
            if (Document.moveevent)
            {
                back.removeEventListener(MouseEvent.MOUSE_MOVE, Document.MouseMove, false);
            }
            Document.Reset();
            holder.contextMenu = null;
            return;
        }// end function

        public function ForceActivate() : void
        {
            ed.ActivateCanvas(this);
            return;
        }// end function

        public function Activate(... args) : void
        {
            this.removeEventListener(MouseEvent.MOUSE_DOWN, ed.ActivateCanvasEvent);
            closeme.addEventListener(MouseEvent.MOUSE_UP, CloseClick, false, 0, true);
            maxme.addEventListener(MouseEvent.MOUSE_UP, MaxClick, false, 0, true);
            back.addEventListener(MouseEvent.ROLL_OUT, this.CanvasOut, false, 0, true);
            back.addEventListener(MouseEvent.ROLL_OVER, this.CanvasOver, false, 0, true);
            coating.Animate();
            return;
        }// end function

        public function Deactivate(Document:Boolean = false) : void
        {
            closeme.removeEventListener(MouseEvent.MOUSE_UP, CloseClick, false);
            maxme.removeEventListener(MouseEvent.MOUSE_UP, MaxClick, false);
            back.removeEventListener(MouseEvent.ROLL_OUT, this.CanvasOut, false);
            back.removeEventListener(MouseEvent.ROLL_OVER, this.CanvasOver, false);
            coating.Freeze();
            if (Document)
            {
                this.Dispose();
            }
            else
            {
                this.addEventListener(MouseEvent.MOUSE_DOWN, ed.ActivateCanvasEvent, false, 0, true);
            }
            return;
        }// end function

        public function Dispose() : void
        {
            var _loc_1:Layer = null;
            while (holder.numChildren > 0)
            {
                
                holder.removeChildAt(0);
            }
            coating.bitmapData.dispose();
            coating = null;
            this.screenshot.dispose();
            this.screenshot = null;
            while (this.document.numChildren > 0)
            {
                
                _loc_1 = this.document.GetLayer(0);
                _loc_1.RemoveObject();
                this.document.removeChildAt(0);
                _loc_1 = null;
            }
            this.document = null;
            ed = null;
            if (this.selection != null)
            {
                this.selection.Dispose();
                this.selection = null;
            }
            if (this.history != null)
            {
                this.history = null;
            }
            this.clip = null;
            ztb.removeEventListener(NumberEvent.CHANGE, this.SetZoomEvent);
            grip.removeEventListener(MouseEvent.MOUSE_DOWN, this.GripMouseDown, false);
            grip.removeEventListener(MouseEvent.MOUSE_OVER, GripMouseOver, false);
            grip.removeEventListener(MouseEvent.MOUSE_OUT, GripMouseOut, false);
            hscroll.removeEventListener(ScrollEvent.SCROLL, this.HorizontalScroll, false);
            vscroll.removeEventListener(ScrollEvent.SCROLL, this.VerticalScroll, false);
            drag.removeEventListener(MouseEvent.MOUSE_DOWN, DragMouseDown, false);
            drag.removeEventListener(MouseEvent.MOUSE_UP, DragMouseUp, false);
            return;
        }// end function

        public function Message(Document:String) : void
        {
            message.Show(Document);
            return;
        }// end function

        private function GripMouseMove(event:MouseEvent) : void
        {
            this.Resize(grip.x + 20, grip.y + 20, true);
            this.UpdateHolderSize();
            return;
        }// end function

        private function GripMouseDown(event:MouseEvent) : void
        {
            vscroll.halt = true;
            hscroll.halt = true;
            ed.cursor.freeze = true;
            grip.startDrag(false, new Rectangle(250, 150, 2000, 2000));
            stage.addEventListener(MouseEvent.MOUSE_MOVE, this.GripMouseMove, true, 1, false);
            stage.addEventListener(MouseEvent.MOUSE_UP, this.GripMouseUp, true, 1, false);
            return;
        }// end function

        private function GripMouseUp(event:MouseEvent) : void
        {
            grip.stopDrag();
            vscroll.halt = false;
            hscroll.halt = false;
            ed.cursor.freeze = false;
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.GripMouseMove, true);
            stage.removeEventListener(MouseEvent.MOUSE_UP, this.GripMouseUp, true);
            this.GripMouseMove(null);
            if (event.target != grip)
            {
                ed.cursor.Set(ToolType.None);
                ed.tool.Reset();
            }
            return;
        }// end function

        public function SetZoomEvent(event:NumberEvent) : void
        {
            ed.navigator.SetZoom(event.val, true, true);
            return;
        }// end function

        public function VerticalScroll(event:ScrollEvent) : void
        {
            this.document.y = -Math.round(event.scrolled);
            this.CheckBounds();
            this.UpdateAfterPan(true);
            return;
        }// end function

        public function HorizontalScroll(event:ScrollEvent) : void
        {
            this.document.x = -Math.round(event.scrolled);
            this.CheckBounds();
            this.UpdateAfterPan(true);
            return;
        }// end function

        public function UpdateHolderSize() : void
        {
            masking.width = canvaswidth / this.zoomlevel > this.dw ? (int(this.dw * this.zoomlevel)) : (canvaswidth);
            masking.height = canvasheight / this.zoomlevel > this.dh ? (int(this.dh * this.zoomlevel)) : (canvasheight);
            this.clip.width = Math.round(masking.width / this.zoomlevel);
            this.clip.height = Math.round(masking.height / this.zoomlevel);
            if (canvaswidth / this.zoomlevel > this.dw)
            {
                var _loc_1:* = 4 + Math.round((canvaswidth - this.dw * this.zoomlevel) * 0.5);
                holder.x = 4 + Math.round((canvaswidth - this.dw * this.zoomlevel) * 0.5);
                var _loc_1:* = _loc_1;
                coating.x = _loc_1;
                masking.x = _loc_1;
            }
            else
            {
                var _loc_1:int = 4;
                holder.x = 4;
                var _loc_1:* = _loc_1;
                coating.x = _loc_1;
                masking.x = _loc_1;
            }
            if (canvasheight / this.zoomlevel > this.dh)
            {
                var _loc_1:* = 22 + Math.round((canvasheight - this.dh * this.zoomlevel) * 0.5);
                holder.y = 22 + Math.round((canvasheight - this.dh * this.zoomlevel) * 0.5);
                var _loc_1:* = _loc_1;
                coating.y = _loc_1;
                masking.y = _loc_1;
            }
            else
            {
                var _loc_1:int = 22;
                holder.y = 22;
                var _loc_1:* = _loc_1;
                coating.y = _loc_1;
                masking.y = _loc_1;
            }
            coating.Resize(masking.width, masking.height);
            this.CheckBounds();
            hscroll.SetContentSize(Math.round(this.dw * this.zoomlevel));
            vscroll.SetContentSize(Math.round(this.dh * this.zoomlevel));
            if (AppState.Maximized && grip.visible)
            {
                grip.visible = false;
            }
            else if (!AppState.Maximized && !grip.visible)
            {
                grip.visible = true;
            }
            this.UpdateAfterPan();
            return;
        }// end function

        public function UpdateAfterPan(Document:Boolean = false, Document:Boolean = false) : void
        {
            this.clip.x = -int(this.document.x / this.zoomlevel);
            this.clip.y = -int(this.document.y / this.zoomlevel);
            this.clipsx = -Math.round(this.document.x / this.zoomlevel);
            this.clipsy = -Math.round(this.document.y / this.zoomlevel);
            this.clipox = Math.round(this.document.x + this.clip.x * this.zoomlevel);
            this.clipoy = Math.round(this.document.y + this.clip.y * this.zoomlevel);
            coating.Clear();
            coating.Redraw();
            if (!Document)
            {
                vscroll.SetScrollAmount(-this.document.y);
                hscroll.SetScrollAmount(-this.document.x);
            }
            if (!Document)
            {
                ed.navigator.RedrawMarker();
            }
            return;
        }// end function

        public function UpdateAfterEdit(Document:int = -1, Document:uint = 16777215) : void
        {
            ed.layers.UpdateLayerBitmap(Document);
            if (this.screenshot.width != this.dw || this.screenshot.height != this.dh)
            {
                this.screenshot = new BitmapData(this.dw, this.dh, true, Document);
            }
            else
            {
                this.screenshot.fillRect(this.screenshot.rect, Document);
            }
            this.screenshot.draw(this.document);
            return;
        }// end function

        public function CheckBounds() : void
        {
            if (this.document.x > 0)
            {
                this.document.x = 0;
            }
            else if (this.document.x + this.dw * this.zoomlevel < masking.width)
            {
                this.document.x = masking.width - this.dw * this.zoomlevel;
            }
            if (this.document.y > 0)
            {
                this.document.y = 0;
            }
            else if (this.document.y + this.dh * this.zoomlevel < masking.height)
            {
                this.document.y = masking.height - this.dh * this.zoomlevel;
            }
            return;
        }// end function

        public function SetAnchor(Document:Point) : void
        {
            this.document.x = -Math.round(Document.x * this.zoomlevel);
            this.document.y = -Math.round(Document.y * this.zoomlevel);
            this.CheckBounds();
            this.UpdateAfterPan(false, true);
            return;
        }// end function

        public function Zoom(Document:int, Document:Boolean = false) : void
        {
            if (!Document)
            {
                ztb.value = Document;
            }
            this.zoomlevel = Document * 0.01;
            if (this.dw * this.zoomlevel + stage.stageWidth > 8050 || this.dh * this.zoomlevel + stage.stageHeight > 8050)
            {
                if (this.dw > this.dh)
                {
                    this.zoomlevel = (8050 - stage.stageWidth) / this.dw;
                }
                else
                {
                    this.zoomlevel = (8050 - stage.stageHeight) / this.dh;
                }
            }
            this.document.scaleY = this.zoomlevel;
            this.document.scaleX = this.zoomlevel;
            masking.width = canvaswidth / this.zoomlevel > this.dw ? (int(this.dw * this.zoomlevel)) : (canvaswidth);
            masking.height = canvasheight / this.zoomlevel > this.dh ? (int(this.dh * this.zoomlevel)) : (canvasheight);
            this.document.x = -Math.round(this.clipsx * this.zoomlevel + (this.clip.width * this.zoomlevel - masking.width) / 2);
            this.document.y = -Math.round(this.clipsy * this.zoomlevel + (this.clip.height * this.zoomlevel - masking.height) / 2);
            this.UpdateHolderSize();
            return;
        }// end function

        public function GetOffsetMousePosition(E:\editor;core\ui;Canvas.as:Point) : Point
        {
            return new Point((Math.ceil(this.document.mouseX) - 1) - E:\editor;core\ui;Canvas.as.x, int(this.document.mouseY) - E:\editor;core\ui;Canvas.as.y);
        }// end function

        public function GetMousePosition() : Point
        {
            return new Point((Math.ceil(this.document.mouseX) - 1), int(this.document.mouseY));
        }// end function

        public function GetAverageMousePosition() : Point
        {
            return new Point(Math.round(-this.document.x / this.zoomlevel + coating.mouseX / this.zoomlevel), Math.round(-this.document.y / this.zoomlevel + coating.mouseY / this.zoomlevel));
        }// end function

        public function GetRealMousePosition() : Point
        {
            return new Point((Math.ceil(coating.mouseX) - 1), int(coating.mouseY));
        }// end function

        public function CanvasOver(... args) : void
        {
            AppState.OnCanvas = true;
            ed.cursor.Set(ed.tool.type);
            return;
        }// end function

        public function CanvasOut(... args) : void
        {
            AppState.OnCanvas = false;
            ed.cursor.Set(ToolType.None);
            return;
        }// end function

        public function CropCanvas(Document:Rectangle) : void
        {
            this.DeselectAll();
            this.history.Prepare(Action.CropTool, true);
            this.document.Crop(Document);
            SetImageSizeInfo(this.dw, this.dh);
            this.UpdateHolderSize();
            this.UpdateAfterEdit();
            ed.navigator.SetReference(this);
            ed.layers.SetReference(this.document);
            return;
        }// end function

        public function ResizeCanvas(Document:int, Document:int, Document:int) : void
        {
            this.DeselectAll();
            this.history.Prepare(Action.DocumentNewsize, true);
            this.document.Newsize(Document, Document, Document);
            SetImageSizeInfo(this.dw, this.dh);
            this.UpdateHolderSize();
            this.UpdateAfterEdit();
            ed.navigator.SetReference(this);
            ed.layers.SetReference(this.document);
            return;
        }// end function

        public function ResizeImage(Document:int, Document:int) : void
        {
            this.DeselectAll();
            this.history.Prepare(Action.DocumentResize, true);
            this.document.Resize(Document, Document);
            SetImageSizeInfo(this.dw, this.dh);
            this.UpdateHolderSize();
            this.UpdateAfterEdit();
            ed.navigator.SetReference(this);
            ed.layers.SetReference(this.document);
            return;
        }// end function

        public function FlipImage(Document:FlipType) : void
        {
            this.DeselectAll();
            this.history.Prepare(Action.DocumentFlip, true);
            this.document.Flip(Document, true);
            this.UpdateAfterEdit();
            ed.navigator.SetReference(this);
            ed.layers.SetReference(this.document);
            return;
        }// end function

        public function FlipLayer(Document:FlipType) : void
        {
            this.DeselectAll();
            this.history.Prepare(Action.LayerFlip, true);
            this.document.Flip(Document);
            this.UpdateAfterEdit();
            return;
        }// end function

        public function RotateImage(Document:int) : void
        {
            this.DeselectAll();
            this.history.Prepare(Action.DocumentRotate, true);
            this.document.Rotate(Document, true);
            SetImageSizeInfo(this.dw, this.dh);
            this.UpdateHolderSize();
            this.UpdateAfterEdit();
            ed.navigator.SetReference(this);
            ed.layers.SetReference(this.document);
            return;
        }// end function

        public function RotateLayer(Document:int) : void
        {
            this.DeselectAll();
            this.history.Prepare(Action.LayerRotate, true);
            this.document.Rotate(Document);
            this.UpdateAfterEdit();
            return;
        }// end function

        public function get hasSelection() : Boolean
        {
            return Boolean(this.selection != null && this.selection.width > 0 && this.selection.height > 0);
        }// end function

        public function SelectAll() : void
        {
            this.history.Prepare(Action.SelectAll, true);
            if (this.selection == null)
            {
                this.AddSelection();
            }
            else
            {
                coating.Clear();
            }
            this.selection.SelectAll();
            this.selection.CreateOutline();
            return;
        }// end function

        public function DeselectAll() : void
        {
            if (this.selection != null)
            {
                this.history.Prepare(Action.Deselect, true);
                this.RemoveSelection();
            }
            return;
        }// end function

        public function InvertSelection() : void
        {
            if (this.selection != null)
            {
                this.history.Prepare(Action.InvertSelection, true);
                this.selection.Invert();
                this.selection.CreateOutline();
                coating.Clear();
            }
            return;
        }// end function

        public function AddSelection() : void
        {
            this.selection = new Selection(this.dw, this.dh);
            coating.Animate();
            return;
        }// end function

        public function RemoveSelection() : void
        {
            this.selection = null;
            coating.Deanimate();
            ed.navigator.SetSelectionSize(0, 0);
            return;
        }// end function

        public function SetSelection(Document:Selection) : void
        {
            if (Document == null)
            {
                this.RemoveSelection();
            }
            else
            {
                this.selection = Document;
                coating.Clear();
                coating.Animate();
                ed.navigator.SetSelectionSize(Document.width, Document.height);
            }
            return;
        }// end function

        private function SetContextMenu(Document:ToolType) : void
        {
            var _arg1:* = Document;
            var type:* = _arg1;
            this.cm = new ContextMenu();
            this.cm.hideBuiltInItems();
            switch(type)
            {
                case ToolType.Hand:
                case ToolType.Zoom:
                {
                    UI.AddToContext(this.cm, "rm_zoom_in", ed.cm.ZoomIn);
                    UI.AddToContext(this.cm, "rm_zoom_out", ed.cm.ZoomOut);
                    UI.AddToContext(this.cm, "rm_actual_pixels", ed.cm.ZoomActualPixels, true);
                    UI.AddToContext(this.cm, "rm_show_all", ed.cm.ZoomShowAll);
                    break;
                }
                case ToolType.Blur:
                case ToolType.Brush:
                case ToolType.Pencil:
                case ToolType.Sharpen:
                case ToolType.Clone:
                case ToolType.Eraser:
                case ToolType.Burn:
                case ToolType.Dodge:
                case ToolType.Smudge:
                case ToolType.ColorReplace:
                {
                    UI.AddToContext(this.cm, "rm_brush_size_larger", ed.cm.MakeBrushLarger);
                    UI.AddToContext(this.cm, "rm_brush_size_smaller", ed.cm.MakeBrushSmaller);
                    UI.AddToContext(this.cm, "rm_brush_hardness_harder", ed.cm.MakeBrushHarder, true);
                    UI.AddToContext(this.cm, "rm_brush_hardness_softer", ed.cm.MakeBrushSofter);
                    break;
                }
                case ToolType.Wand:
                case ToolType.Lasso:
                case ToolType.Marquee:
                {
                    UI.AddToContext(this.cm, "rm_select_all", ed.cm.SelectAll);
                    UI.AddToContext(this.cm, "rm_deselect_all", function ()
            {
                ed.cm.DeselectAll(true);
                return;
            }// end function
            );
                    UI.AddToContext(this.cm, "rm_invert_selection", ed.cm.InvertSelection);
                    UI.AddToContext(this.cm, "rm_add_layer_mask", ed.cm.AddLayerMask, true);
                    UI.AddToContext(this.cm, "rm_free_transform", ed.cm.FreeTransform);
                    break;
                }
                default:
                {
                    break;
                }
            }
            this.contextMenu = this.cm;
            return;
        }// end function

    }
}
